﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ADDDF.Infrastructure;

namespace ADDDF.Infrastructure.Test
{
    [TestClass]
    public class RepositoryFrameworkUnitTest
    {
        [TestMethod]
        public void Repository_Test()
        {
            PartyRepository.Reset(100); // start key numbering from 100

            UnitOfWork unitOfWork = new UnitOfWork();
            IPartyRepository repo = new PartyRepository();

            PartyEntity p1 = new PartyEntity(EntityHelper.NewKey(), "p1");

            unitOfWork.RegisterAdded(p1, repo);
            unitOfWork.Commit();

            Assert.IsNotNull(p1.Key);
            Assert.AreEqual(100, p1.Key);

            PartyEntity p1_recon = repo.FindByKey(p1.Key);

            Assert.IsNotNull(p1_recon);
            Assert.IsTrue(p1_recon.SameKeyAs(p1));

            PartyEntity p2 = new PartyEntity(EntityHelper.NewKey(), "p2");

            unitOfWork.RegisterAdded(p2, repo);
            unitOfWork.Commit();

            Assert.IsNotNull(p2.Key);
            Assert.AreEqual(101, p2.Key);
            Assert.AreEqual(2, repo.FindAll().ToList().Count);
            Assert.AreEqual(1, repo.FindByName("p1").Count);

            PartyEntity p2b = new PartyEntity(p2.Key, "p1");

            unitOfWork.RegisterChanged(p2b, (IRepository) repo);
            unitOfWork.Commit();

            Assert.AreEqual(2, repo.FindAll().ToList().Count);
            Assert.AreEqual(2, repo.FindByName("p1").Count);

            unitOfWork.RegisterRemoved(p2b, repo);
            unitOfWork.Commit();

            Assert.AreEqual(1, repo.FindAll().ToList().Count);
        }

        //[TestMethod]
        //public void Repository_NonNullEntityKey()
        //{
        //    UnitOfWork unitOfWork = new UnitOfWork();
        //    IPartyRepository repo = new PartyRepository();

        //    PartyEntity p0 = new PartyEntity("sup");

        //    try
        //    {
        //        repo.Change(p0);
        //        Assert.Fail("Expect D3NullKeyException when entity key is null");
        //    }
        //    catch (D3NullKeyException)
        //    {
        //    }

        //    try
        //    {
        //        repo.Remove(p0);
        //        Assert.Fail("Expect D3NullKeyException when entity key is null");
        //    }
        //    catch (D3NullKeyException)
        //    {
        //    }
        //}

        [TestMethod]
        public void Repository_UseGuidAsKey()
        {
            UnitOfWork unitOfWork = new UnitOfWork();
            IPartyRepository repo = new PartyRepositoryGUIDAsKey();

            PartyEntity p1 = new PartyEntity(Guid.NewGuid(), "p1");

            unitOfWork.RegisterAdded(p1, (IRepository)repo);
            unitOfWork.Commit();

            Assert.IsTrue(p1.Key is Guid);
            
            PartyEntity p1_recon = repo.FindByKey(p1.Key);

            Assert.IsNotNull(p1_recon);
            Assert.IsTrue(p1_recon.SameKeyAs(p1));

            PartyEntity p2 = new PartyEntity(Guid.NewGuid(), "p2");

            unitOfWork.RegisterAdded(p2, (IRepository)repo);
            unitOfWork.Commit();

            Assert.AreEqual(2, repo.FindAll().ToList().Count);
            Assert.AreEqual(1, repo.FindByName("p1").Count);

            PartyEntity p2b = new PartyEntity(p2.Key, "p1");

            unitOfWork.RegisterChanged(p2b, (IRepository)repo);
            unitOfWork.Commit();

            Assert.AreEqual(2, repo.FindAll().ToList().Count);
            Assert.AreEqual(2, repo.FindByName("p1").Count);

            unitOfWork.RegisterRemoved(p2b, (IRepository)repo);
            unitOfWork.Commit();

            Assert.AreEqual(1, repo.FindAll().ToList().Count);
        }
    }
}
